import java.util.Scanner;

/**
 * @Author YuanYuan
 * @Date 2022/12/2
 * @Time 10:18
 * 检验信用卡
 * ①卡号13到16位之间
 * ②遵循首位4Visa卡,5万事达卡,37美国运通卡,6 Divcover卡
 * ③Luhn检查或(Mod10检查)
 * 1.从右到左每第二个数字加倍,如果将一位数加倍得到一个两位数,则将两位数相加得到一位数
 * 2. 把步骤1所有个位数相加
 * 3. 把卡号中所有奇数位的数字从右到左相加
 * 4. 将步骤2和步骤3的结果相加
 * 5. 如果步骤4的结果能被10整除,则卡号有效,否则无效
 */
public class TestDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入信用卡账号:");
        long number = scanner.nextLong();

        if(isValid(number)) {
            System.out.println(number + " is valid");
        }else {
            System.out.println(number + " is invalid");
        }
    }

    private static boolean isValid(long number) {

        long n = number;
        int singlesum = 0;
        int doublesum = 0;

        //先判断长度是否合理
        int numberlong = sumLong(number);

        if(numberlong<13 || numberlong >16) {
            return false;
        }
        //判断是否是合理的银行
        if(!isBank(number,5) && !isBank(number,6)&&!isBank(number,4)&& !isBank(number,37)) {
            return false;
        }
        n = number/10;
        while(n>0) {
            int count = (int) ((n%10)*2);
            int countsum = 0;
            while(count > 0) {
                int tem = count%10;
                count/=10;
                countsum+=tem;
            }
            //把步骤一中的所有个位数相加
            doublesum+=countsum;
            n/=100;
        }
        n = number;
        //把卡号中所有奇数位相加
        while(n>0) {
            long count = n%10;
            singlesum+=count;
            n/=100;
        }
        //将步骤2和步骤3的结果相加
        int sum = singlesum + doublesum;

        if(0 == sum%10) {
            return true;
        }else {
            return false;
        }

    }

    private static boolean isBank(long number, int i) {
        int numsize = sumLong(number);
        long n = number;
        if(37 == i) {
            n/= Math.pow(10,numsize-2);
        }else{
            n/=Math.pow(10,numsize-1);
        }

        if(n!=i) {
            return false;
        }else {
            return true;
        }
    }

    private static int sumLong(long number) {
        long n = number;
        int numberlong = 0;
        while(n>0) {
            numberlong++;
            n/=10;
        }
        return numberlong;
    }
}
